# from requests import Response
import os

from django.core.exceptions import ObjectDoesNotExist
from django.db import transaction
from django.http import JsonResponse
from django.utils import timezone
from rest_framework import generics, status, viewsets
from rest_framework.decorators import action
from rest_framework.views import APIView, Response

from home.models import ProductCategory, DishCategory, Product, Dish, Unit, Inventory, SalesRecord, \
    Commodity, DishProduct
from user.models import User
from utils.common_response import APIResponse
from .serializers import ProductSerializer, DishCategoryGetSerializer, ProductCategorySerializer, \
    DishSerializer, SalesRecordSerializer, CommoditySerializer, CreateSerializer, PurchaseSerializers, \
    DishSeachSerializer
from .serializers import UnitSerializer, ProductSeachSerializer
from rest_framework.mixins import CreateModelMixin, RetrieveModelMixin, ListModelMixin, UpdateModelMixin, \
    DestroyModelMixin
from rest_framework.viewsets import GenericViewSet, ViewSet
from .pagination import MyPagination
from rest_framework.generics import GenericAPIView, RetrieveUpdateDestroyAPIView


# from .dish_filter import


# ---------------------------------------单位curd=基于APIView+序列化类+Response 写接口------------------------


class UnitView(APIView):
    # authentication_classes = []  # 局部禁用
    permission_classes = []
    throttle_classes = []

    def get(self, request):
        # 只是为了验证之前讲过的
        print(request.method)
        print(request._request)
        print(type(self.request))
        # 获取前端传递的参数，假设参数名为 is_dish
        is_dish = request.query_params.get('is_dish', None)

        # 根据参数值过滤单位
        if is_dish is not None:
            units = Unit.objects.filter(is_dish_unit=is_dish)
        else:
            units = Unit.objects.all()
        # 使用序列化类来完成---》得有个序列化类
        # instance要序列化的数据books queryset对象
        # many=True 只要是queryset对象要传many=True，如果是单个对象就不用传
        ser = UnitSerializer(instance=units, many=True)
        custom_data = {'code': 100, 'msg': '获取所有单位成功', 'data': ser.data}
        return Response(custom_data, status=status.HTTP_200_OK)
        # return Response(ser.data)  # 无论是列表还是字典都可以序列化

    def post(self, request):
        # requset.data  # 前端提交的要保存的数据----》校验数据---》存
        ser = UnitSerializer(data=request.data)  # 把前端传入的要保存的数据，给data参数
        # 校验数据
        if ser.is_valid():
            # 保存---->需要自己写，要在序列化类BookSerializer中写----》create方法
            ser.save()  # 调用ser.save,自动触发咱们写的create，保存起来
            return Response({'code': 100, 'msg': '新增成功', 'data': ser.data})
        else:
            return Response({'code': 101, 'msg': ser.errors})


class UnitDetailView(APIView):
    # authentication_classes = []  # 局部禁用
    permission_classes = []
    throttle_classes = []

    # def get(self, request,pk):
    def get(self, request, *args, **kwargs):
        unit = Unit.objects.filter(pk=kwargs.get('pk')).first()
        # 序列化
        ser = UnitSerializer(instance=unit)
        custom_data = {'code': 100, 'msg': '获取指定单位成功', 'data': ser.data}
        return Response(custom_data, status=status.HTTP_200_OK)
        # return Response(ser.data)

    def put(self, request, pk):
        unit = Unit.objects.filter(pk=pk).first()
        # 反序列化保存 ---借助于序列化类
        ser = UnitSerializer(data=request.data, instance=unit)
        if ser.is_valid():
            ser.save()  # 由于没有重写update，所以这报错
            return Response({'code': 100, 'msg': '修改成功', 'data': ser.data})
        else:
            return Response({'code': 101, 'msg': ser.errors})

    def delete(self, requset, pk):
        Unit.objects.filter(pk=pk).delete()
        return Response({'code': 100, 'msg': '删除成功'})


# -----------------------------GenericAPIView---》继承了APIView，有很多新的属性和方法---------
# 以后咱们可以基于这个类，来写5个接口
# 5个接口的效果一样，但是咱们代码 可用性变高了
# GenericAPIView 属性和方法
'''
# 属性
1 queryset:要序列化或反序列化的表模型数据
2 serializer_class：使用的序列化类
3 lookup_field ：查询单条的路由分组分出来的字段名
4 filter_backends：过滤类的配置(了解)
5 pagination_class：分页类的配置(了解)

# 方法
1 get_queryset   ：获取要序列化的对象
2 get_object  ：获取单个对象
3 get_serializer ：获取序列化类  ，跟它差不多的get_serializer_class，一般重写它，不调用它
4 filter_queryset  ：过滤有关系(了解)
'''


class ProductCategoryView(GenericAPIView):
    queryset = ProductCategory.objects.all()
    serializer_class = ProductCategorySerializer
    # authentication_classes = []  # 局部禁用
    permission_classes = []
    throttle_classes = []

    def get(self, request):
        store_id = request.headers.get('team')  # 获取请求头中的门店 ID
        if store_id:
            # 根据门店 ID 进行过滤
            objs = self.get_queryset().filter(team_id=store_id)
        else:
            objs = self.get_queryset()
        ser = self.get_serializer(instance=objs, many=True)  # 后期可以重写get_serializer_class，指定使用哪个序列化类来序列化
        custom_data = {'code': 100, 'msg': '获取所有菜品成功', 'data': ser.data}
        return Response(custom_data, status=status.HTTP_200_OK)

    def post(self, request):
        print(request.data)
        ser = self.get_serializer(data=request.data)
        if ser.is_valid():
            ser.save()
            # 咱们现在只有ser序列化类的对象，但是咱们想要，新增的对象---》序列化成字典---》大前提，序列化类中的create方法一定要返回新增的对象
            return Response({'code': 100, 'msg': '新增成功', 'data': ser.data})
        else:
            return Response({'code': 101, 'msg': ser.errors})


class ProductCategoryDetailView(GenericAPIView):
    queryset = ProductCategory.objects.all()
    serializer_class = ProductCategorySerializer
    # authentication_classes = []  # 局部禁用
    permission_classes = []
    throttle_classes = []

    def get(self, request, pk):
        obj = self.get_object()  # 获取单条
        ser = self.get_serializer(instance=obj)
        custom_data = {'code': 100, 'msg': '获取指定菜品成功', 'data': ser.data}
        return Response(custom_data, status=status.HTTP_200_OK)

    def put(self, request, pk):
        obj = self.get_object()
        ser = self.get_serializer(instance=obj, data=request.data)
        if ser.is_valid():
            ser.save()
            return Response({'code': 100, 'msg': '修改成功', 'data': ser.data})
        else:
            return Response({'code': 101, 'msg': ser.errors})

    def delete(self, request, pk):
        self.get_object().delete()
        return Response({'code': 100, 'msg': '删除成功'})


# ----------------------------菜品curd=基于GenericAPIView+5个视图扩展类写接口

class DishView(GenericAPIView, ListModelMixin, CreateModelMixin):
    queryset = Dish.objects.all()
    serializer_class = DishSerializer
    # authentication_classes = []  # 局部禁用
    permission_classes = []
    throttle_classes = []
    pagination_class = MyPagination  # 选择分页类

    def get_queryset(self):
        queryset = super().get_queryset()
        created_at = self.request.query_params.get('created_at')
        team_id = self.request.headers.get('team')  # 获取请求头中的门店ID
        category_id = self.request.query_params.get('category_id', None)

        if created_at:
            # 如果日期字符串不为空，则解析日期字符串成为datetime对象，并过滤记录
            created_at = timezone.datetime.strptime(created_at, '%Y-%m-%d')
            queryset = queryset.filter(created_at__date=created_at)

        # 构建基础查询集
        if category_id:
            queryset = queryset.filter(category=category_id)

        if team_id:
            # 根据门店ID过滤查询结果
            queryset = queryset.filter(team=team_id)
        return queryset.order_by('-created_at')  # 按照 created_at 字段的倒序排序

    def get(self, request):
        data = self.list(request)
        custom_data = {'code': 100, 'msg': '获取所有菜品成功', 'data': data.data}
        return Response(custom_data, status=status.HTTP_200_OK)

    def post(self, request):
        print(request.data, 1111)
        print(type(request.data))
        # 获取 request.data
        # 获取 request.data
        data = request.data

        # # 如果 products 是字符串列表，将其解析为 JSON 对象
        # if 'products' in data and isinstance(data.getlist('products'), list):
        #     try:
        #         products_list = [json.loads(product) for product in data.getlist('products')]
        #         data['products'] = products_list
        #     except json.JSONDecodeError as e:
        #         return Response({'error': 'Invalid JSON data in products field'}, status=400)

        data = self.create(request)

        custom_data = {'code': 100, 'msg': '添加菜品成功', 'data': data.data}
        return Response(custom_data, status=status.HTTP_200_OK)


class DishDetailView(GenericAPIView, RetrieveModelMixin, UpdateModelMixin, DestroyModelMixin):
    queryset = Dish.objects.all()
    serializer_class = DishSerializer
    # authentication_classes = []  # 局部禁用
    permission_classes = []
    throttle_classes = []

    def get(self, request, *args, **kwargs):
        data = self.retrieve(request, *args, **kwargs)
        custom_data = {'code': 100, 'msg': '添加指定菜品成功', 'data': data.data}
        return Response(custom_data, status=status.HTTP_200_OK)

    def put(self, request, *args, **kwargs):
        print('lail')
        data = self.update(request, *args, **kwargs)
        # Customize the response data as needed
        custom_data = {'code': 100, 'msg': '修改指定菜品成功', 'data': data.data}
        return Response(custom_data, status=status.HTTP_200_OK)

    def delete(self, request, *args, **kwargs):
        instance = self.get_object()
        print(instance)

        # 获取与菜品关联的菜品货品表
        dish_products = DishProduct.objects.filter(dish=instance)

        # 检查菜品货品表是否有相关记录
        if dish_products.exists():
            # 如果存在相关记录，先删除与菜品关联的货品记录
            dish_products.delete()
            # 如果存在相关记录，继续执行删除操作
            with transaction.atomic():
                self.destroy(request, *args, **kwargs)
        else:
            # 如果不存在相关记录，删除菜品并返回相应信息
            instance.delete()

        custom_data = {'code': 100, 'msg': '删除指定菜品成功'}
        return Response(custom_data, status=status.HTTP_200_OK)


# ------------供应商=通过ModelViewSet编写5个接口----------------------------------


# 视图类
# class SupplierView(ModelViewSet):  # 查询所有，新增一个
#     queryset = Supplier.objects.all()
#     serializer_class = SupplierSerializers
#     # authentication_classes = []  # 局部禁用
#     permission_classes = []
#     throttle_classes = []
#
#
# # -------------通过ReadOnlyModelViewSet编写2个只读接口------
# class SupplierReadOnlyView(ReadOnlyModelViewSet):  # 查询所有，新增一个
#     queryset = Supplier.objects.all()
#     serializer_class = SupplierSerializers
#     authentication_classes = []  # 局部禁用
#     permission_classes = []
#     throttle_classes = []


# 添加菜品分类
# class DishCategoryCreateView(CreateModelMixin, GenericViewSet):
#     queryset = ProductCategory.objects.all()
#     serializer_class = DishCategoryGetSerializer
#     authentication_classes = []  # 局部禁用
#     permission_classes = []
#     throttle_classes = []
#
#     def create(self, request, *args, **kwargs):
#         res = super().create(request, *args, **kwargs)
#         return APIResponse(data=res.data)

# -----------------------------菜品分类=动态路由+generic+五个扩展类---------------------------------
# 获取菜品分类所有和单个
class DishCategoryGetView(CreateModelMixin,
                          ListModelMixin,
                          RetrieveModelMixin,
                          UpdateModelMixin,
                          DestroyModelMixin,
                          GenericViewSet):
    queryset = DishCategory.objects.all()
    serializer_class = DishCategoryGetSerializer
    # pagination_class = MyPagination
    # filter_backends = [MyFilter, ]
    # authentication_classes = []  # 局部禁用
    permission_classes = []
    throttle_classes = []

    def create(self, request, *args, **kwargs):
        print(request.data)
        res = super().create(request, *args, **kwargs)
        return APIResponse(data=res.data)

    def list(self, request, *args, **kwargs):
        # res = super().list(request, *args, **kwargs)
        store_id = request.headers.get('team')  # 获取请求头中的门店 ID
        queryset = self.queryset.filter(team_id=store_id) if store_id else self.queryset
        serializer = self.get_serializer(instance=queryset, many=True)
        return APIResponse(data=serializer.data)

    def retrieve(self, request, *args, **kwargs):
        res = super().retrieve(request, *args, **kwargs)
        return APIResponse(data=res.data)

    def update(self, request, *args, **kwargs):
        res = super().update(request, *args, **kwargs)
        return APIResponse(data=res.data)

    def destroy(self, request, *args, **kwargs):
        res = super().destroy(request, *args, **kwargs)
        return APIResponse(data=res.data)

    @action(methods=['POST'], detail=False)
    def login(self, request):
        username = request.data.get('username')
        password = request.data.get('password')
        user = User.objects.filter(username=username, password=password).first()
        if user:
            # 用户存在，登录成功
            # 生成一个随机字符串--uuid
            # token = str(uuid.uuid4())  # 生成一个永不重复的随机字符串
            # # 在userToken表中存储一下：1 从来没有登录过，插入一条，     2 登录过，修改记录
            # # 如果有就修改，如果没有就新增  (if 自己写)
            # # kwargs 传入的东西查找，能找到，使用defaults的更新，否则新增一条
            # UserToken.objects.update_or_create(user=user, defaults={'token': token})
            return Response({'code': '100', 'msg': '登录成功'})
        else:
            return Response({'code': '101', 'msg': '用户名或密码错误'})


# class ProductCreateView(CreateModelMixin, GenericViewSet):
#     queryset = Product.objects.all()
#     serializer_class = ProductSerializer
#     authentication_classes = []  # 局部禁用
# #     permission_classes = []
#     throttle_classes = []
#


# -----------------------------货品=动态路由+generic+五个扩展类---------------------------------
class ProductView(CreateModelMixin,
                  ListModelMixin,
                  RetrieveModelMixin,
                  UpdateModelMixin,
                  DestroyModelMixin,
                  GenericViewSet):
    queryset = Product.objects.all()
    serializer_class = ProductSerializer
    # authentication_classes = []  # 局部禁用
    permission_classes = []
    throttle_classes = []
    pagination_class = MyPagination  # 选择分页类

    def get_serializer_class(self):
        # 根据操作选择不同的序列化类
        if self.action == 'create':
            return CreateSerializer
        elif self.action == 'retrieve':
            return ProductSerializer
        # 默认返回通用的序列化类
        return ProductSerializer  # 或者您想要的默认序列化类

    def get_queryset(self):
        queryset = super().get_queryset()
        created_at = self.request.query_params.get('created_at_gte')
        team_id = self.request.headers.get('team')  # 获取请求头中的门店ID
        category_id = self.request.query_params.get('category_id', None)

        if created_at:
            # 如果日期字符串不为空，则解析日期字符串成为datetime对象，并过滤记录
            created_at = timezone.datetime.strptime(created_at, '%Y-%m-%d')
            queryset = queryset.filter(inventory__created_at__date=created_at)

        # 构建基础查询集
        if category_id:
            queryset = queryset.filter(category=category_id)
        print(team_id)
        if team_id:
            # 根据门店ID过滤查询结果
            queryset = queryset.filter(team=team_id)
        query = self.request.query_params.get('name', '')  # 获取查询参数
        if query:
            # 在这里，name 是数据库表中的字段名，icontains 是一个查询条件，表示不区分大小写地包含指定的字符串
            queryset = queryset.filter(name__icontains=query)  # 模糊查询产品名称
        return queryset.order_by('-created_at')  # 按照 created_at 字段的倒序排序

    def create(self, request, *args, **kwargs):
        res = super().create(request, *args, **kwargs)
        return APIResponse(data=res.data)

    def list(self, request, *args, **kwargs):
        res = super().list(request, *args, **kwargs)
        return APIResponse(data=res.data)

    def retrieve(self, request, *args, **kwargs):
        res = super().retrieve(request, *args, **kwargs)
        return APIResponse(data=res.data)

    def update(self, request, *args, **kwargs):
        res = super().update(request, *args, **kwargs)
        return APIResponse(data=res.data)

    def destroy(self, request, *args, **kwargs):
        res = super().destroy(request, *args, **kwargs)
        return APIResponse(data=res.data)


class InventoryViewSet(CreateModelMixin,
                       ListModelMixin,
                       RetrieveModelMixin,
                       UpdateModelMixin,
                       DestroyModelMixin,
                       GenericViewSet):
    throttle_classes = []
    permission_classes = []
    # queryset = Inventory.objects.all()
    # queryset = Inventory.objects.select_related('product').all()  # Include related product data
    serializer_class = PurchaseSerializers
    pagination_class = MyPagination  # 选择分页类

    # def get_queryset(self):
    #     # 获取前端传入的日期字符串
    #     created_at_str = self.request.query_params.get('created_at')
    #     user_id = self.request.query_params.get('user_id')
    #     store_id = self.request.headers.get('team')  # 获取请求头中的门店ID
    #     # 如果日期字符串为空，则返回所有的库存记录
    #     print("传入的日期", created_at_str)
    #     print("传入的门店", store_id, type(store_id))
    #     if not created_at_str and store_id:
    #         queryset = Inventory.objects.filter(product__team=int(store_id)).select_related('product').order_by(
    #             '-created_at')
    #         return queryset
    #
    #     # 解析日期字符串成为datetime对象
    #     created_at = datetime.strptime(created_at_str, '%Y-%m-%d')
    #
    #     # 过滤库存记录，只返回与指定日期相匹配的记录，并预加载关联的货品数据
    #     queryset = Inventory.objects.filter(created_at__date=created_at,product__team=store_id).select_related('product')
    #
    #     if store_id:
    #         # 根据门店ID过滤查询结果
    #         print(11111111111111111111)
    #
    #         queryset = Inventory.objects.filter(created_at__date=created_at,
    #                                             product__team=int(store_id)).select_related('product').order_by(
    #             '-created_at')
    #     else:
    #         queryset = Inventory.objects.all()  # 或者根据需要返回适当的查询集
    #
    #     if user_id:
    #         queryset = queryset.filter(user_id=user_id)
    #
    #     return queryset.order_by('-created_at')  # 按照 created_at 字段的倒序排序

    def get_queryset(self):
        # 获取前端传入的日期字符串
        created_at = self.request.query_params.get('created_at')
        user_id = self.request.query_params.get('user_id')
        store_id = self.request.headers.get('team')  # 获取请求头中的门店ID

        queryset = Inventory.objects.all().select_related('product')  # 默认查询集为所有库存记录

        if store_id:
            # 根据门店ID过滤查询结果
            queryset = queryset.filter(product__team=int(store_id))

        if created_at:
            # 如果日期字符串不为空，则解析日期字符串成为datetime对象，并过滤记录
            created_at = timezone.datetime.strptime(created_at, '%Y-%m-%d')
            # queryset = queryset.filter(created_at__date=created_at)
            queryset = queryset.filter(stock_in_time__date=created_at)

        if user_id:
            # 如果用户ID不为空，则根据用户ID过滤记录
            queryset = queryset.filter(user_id=user_id)

        return queryset.order_by('-stock_in_time')  # 按照 created_at 字段的倒序排序

    #
    def list(self, request, *args, **kwargs):
        res = super().list(request, *args, **kwargs)
        return APIResponse(data=res.data)

    def perform_update(self, serializer):

        # 获取库存记录对象
        instance = serializer.instance

        # 计算库存变化
        old_weight = instance.weight
        new_weight = serializer.validated_data.get('weight')

        stock_change = int(new_weight) - int(old_weight)

        print(1111111, old_weight, new_weight, stock_change)

        # 更新数据库中的数据
        instance.product_cost_price = serializer.validated_data.get('product_cost_price')
        instance.product_price = serializer.validated_data.get('product_price')
        instance.quantity = serializer.validated_data.get('quantity')
        instance.weight = serializer.validated_data.get('weight')
        instance.volume = serializer.validated_data.get('volume')
        instance.before_weight = serializer.validated_data.get('before_weight')
        instance.stock_in_time = serializer.validated_data.get('stock_in_time')
        instance.procurement = serializer.validated_data.get('procurement')
        instance.current_stock = serializer.validated_data.get('current_stock')

        # 更新关联产品的总库存
        self.update_total_stock(instance.product, stock_change)
        # print(11111)

        # 保存更新后的库存记录
        instance.save()

        # 更新关联产品的总库存
        self.update_total_stock(instance.product, stock_change)

    def update_total_stock(self, product, stock_change):
        # 获取产品关联的最近的一条库存记录
        latest_inventory_record = Inventory.objects.filter(product=product).latest('created_at')

        # 更新最近的库存记录的总库存字段
        if int(latest_inventory_record.current_stock) + stock_change >= 0:
            latest_inventory_record.current_stock = int(latest_inventory_record.current_stock)
            latest_inventory_record.current_stock += stock_change
        else:
            latest_inventory_record.current_stock = 0
        print(int(latest_inventory_record.current_stock), stock_change)
        latest_inventory_record.save()

    def update(self, request, *args, **kwargs):
        # 获取库存记录对象
        instance = self.get_object()

        # 反序列化传入的数据
        serializer = self.get_serializer(instance, data=request.data)
        serializer.is_valid(raise_exception=True)

        # 更新库存记录
        self.perform_update(serializer)

        return APIResponse(data=serializer.data)


class InventoryDetailView(RetrieveUpdateDestroyAPIView):
    queryset = Inventory.objects.all()
    serializer_class = PurchaseSerializers
    throttle_classes = []
    permission_classes = []

    def delete(self, request, *args, **kwargs):
        # 获取库存记录对象
        instance = self.get_object()

        # 获取即将删除的库存记录的数量
        deleted_weight = int(instance.weight)

        # 删除库存记录
        self.perform_destroy(instance)

        # 更新总库存
        self.update_total_stock(instance.product, deleted_weight)

        return APIResponse()

    def perform_destroy(self, instance):
        instance.delete()

    def update_total_stock(self, product, stock_change):
        try:
            # 获取最近的库存记录
            latest_inventory_record = Inventory.objects.filter(product=product).latest('created_at')
        except ObjectDoesNotExist:
            # 如果不存在最近的库存记录，则直接返回
            return
        # latest_inventory_record.current_stock = int(latest_inventory_record.current_stock) - stock_change
        current = int(latest_inventory_record.current_stock)
        if int(latest_inventory_record.current_stock) - stock_change >= 0:
            current -= stock_change
        else:
            latest_inventory_record.current_stock = 0
        latest_inventory_record.save()


class HeadFileView(ViewSet):
    # authentication_classes = []  # 局部禁用
    permission_classes = []
    throttle_classes = []

    #################上传图像接口#######################
    @action(methods=['POST'], detail=False)
    def upload_image(self, request):
        user = request.data.get('user')
        file = request.FILES.get('file')
        #####通过前面存入的user字段来判断给哪个用户存入头像入库
        user_obj = User.objects.all().filter(username=user).first()
        user_obj.icon = file

        user_obj.save()
        icon = 'http://127.0.0.1:8000/media/' + str(user_obj.icon)

        return APIResponse(msg='头像上传成功', icon=icon)

    @action(methods=['POST'], detail=False)
    def upload_image(self, request, *args, **kwargs):
        # 获取上传的文件
        image_file = request.FILES.get('file')
        image_type = request.data.get('image_type')

        if not image_file:
            return Response({'error': 'No file provided'}, status=status.HTTP_400_BAD_REQUEST)

        # 确定存储文件夹
        if image_type == '1':
            folder = 'product_images'
        elif image_type == '2':
            folder = 'dish_images'
        elif image_type == '3':
            folder = 'icon'
        else:
            return JsonResponse({'error': 'Invalid image_type provided'}, status=400)

        # 保存文件到指定路径
        file_path = os.path.join('mao_shi_jie', 'media', folder, image_file.name).replace('\\', '/')

        # Ensure the directory exists
        os.makedirs(os.path.dirname(file_path), exist_ok=True)
        with open(file_path, 'wb') as destination:
            for chunk in image_file.chunks():
                destination.write(chunk)

            # 移除"mao_shi_jie/media/"部分
        relative_path = file_path.replace('mao_shi_jie/media/', '')
        icon = '/media/' + str(relative_path)
        # icon = '/media/' + str(relative_path)

        return APIResponse(msg='图片上传成功', image_url=icon)

        # return Response({'image_url': relative_path}, status=status.HTTP_201_CREATED)


class SalesRecordViewSet(viewsets.ModelViewSet):
    queryset = SalesRecord.objects.all()
    serializer_class = SalesRecordSerializer
    authentication_classes = []  # 局部禁用
    permission_classes = []
    throttle_classes = []

    def create(self, request, *args, **kwargs):
        # 检查请求数据是否为列表形式
        if not isinstance(request.data, list):
            print(type(request.data))
            # 如果不是列表形式，则返回错误响应
            return Response({'detail': 'Request data must be a list'}, status=status.HTTP_400_BAD_REQUEST)

        responses = []

        for data in request.data:
            serializer = self.get_serializer(data=data)
            serializer.is_valid(raise_exception=True)

            # 获取销售记录中的菜品和销售数量
            dish = serializer.validated_data['dish']
            print(dish)
            sales_quantity = serializer.validated_data['sales_quantity']

            # 获取菜品关联的所有货品信息
            dish_products = dish.dish_products.all()
            dish_name = dish.name

            with transaction.atomic():
                # 初始化 stock_out_quantity 变量
                stock_out_quantity = 0
                # 处理销售数量，可以根据实际情况进行逻辑处理
                for dish_product in dish_products:
                    print(
                        f'--------------------------------菜品{dish_name}   需要货品"{dish_product.product}"的 所有库存信息--------------')
                    # 获取具体的货品信息
                    product = dish_product.product
                    # 打印关联的所有 DishProduct 对象

                    name = dish_product.product
                    # 尝试根据 name 查找已存在的货品记录
                    existing_product = Product.objects.filter(name=name).first()
                    print(existing_product, 111)
                    if existing_product:
                        # 如果找到已存在的货品记录，则使用该记录
                        product = existing_product
                    else:
                        # 否则，创建新的货品记录
                        print(
                            'buzdaddadasd'
                        )

                    # 根据货品记录的 ID 获取与该产品相关联的所有库存记录
                    all_inventories = Inventory.objects.filter(product=product)
                    print(all_inventories, 111111111)
                    if not all_inventories:
                        return APIResponse(msg=f'{product}货品库存记录中没有了')

                    # 输出库存记录
                    for inventory in all_inventories:
                        print(f'|{inventory.record_id},'
                              f'| {inventory.stock_in_time},'
                              f'| {inventory.quantity}, '
                              f'|{inventory.current_stock},'
                              f'|{inventory.created_at}')

                    # 找到离现在时间最近的库存记录
                    latest_inventory = all_inventories.filter(created_at__lte=timezone.now()).order_by(
                        '-created_at').first()

                    if latest_inventory:
                        print('最新的一条记录信息：',
                              latest_inventory.record_id,
                              latest_inventory.stock_in_time,
                              latest_inventory.quantity,
                              latest_inventory.current_stock,
                              latest_inventory.created_at)

                        print(type(latest_inventory.current_stock), latest_inventory.current_stock)
                        print(type(sales_quantity), sales_quantity)
                        print(type(dish_product.quantity), dish_product.quantity)
                        if not int(latest_inventory.current_stock) > 0:
                            return APIResponse(msg=f'{product}货品库存记录显示库存总量为负')

                        # 计算需要减去的库存数量或质量
                        stock_out_quantity = int(sales_quantity) * int(dish_product.quantity)  # 这里需要根据具体逻辑计算
                        print(stock_out_quantity)

                        current_stock = int(latest_inventory.current_stock) - int(
                            stock_out_quantity)
                    else:
                        # 如果没有现有的库存记录，将 current_stock 设置为初始数量
                        current_stock = 0

                    # 在这里添加库存记录的逻辑，你可能需要自定义库存的相关字段
                    # 例如 stock_out_time, stock_out_quantity 等
                    # 这里只是示例，具体根据你的模型进行调整
                    Inventory.objects.create(
                        product=product,
                        stock_out_time=serializer.validated_data['sales_date'],
                        stock_out_quantity=stock_out_quantity,
                        current_stock=current_stock
                        # 其他库存记录字段
                    )
                    print(f'--------------------------------{dish_product.product}的信息--------------')

                # 调用父类的 create 方法保存销售记录
                response = super().create(request, *args, **kwargs)
                responses.append(response)

        return Response(responses, status=status.HTTP_200_OK)


class CommodityListCreateView(generics.ListCreateAPIView):
    queryset = Commodity.objects.all()
    serializer_class = CommoditySerializer
    authentication_classes = []  # 局部禁用
    permission_classes = []
    throttle_classes = []
    pagination_class = MyPagination  # 选择分页类

    ''' 
在list方法中，当调用self.get_serializer(queryset, many=True)时，序列化器会经历以下步骤：

初始化：调用__init__方法，该方法初始化序列化器。这可能涉及设置一些默认值或初始化实例变量。

to_representation：调用to_representation方法，将查询集转换为Python数据结构。这包括在CommoditySerializer中指定的所有字段。

转换为JSON格式：然后将to_representation中的数据结构转换为JSON格式。这个过程由Django Rest Framework的默认实现处理。

序列化：然后，JSON数据由serializer.data返回，这是一个触发内部序列化过程的属性。

因此，序列化器执行的任务基本上是将模型实例转换为适合JSON表示的格式，并且还允许您在此转换过程中添加任何自定义逻辑。
    '''

    def list(self, request, *args, **kwargs):
        # 获取分页数据
        page = self.paginate_queryset(self.queryset)
        if page is not None:
            serializer = self.get_serializer(page, many=True)
            response_data = {'code': 100,
                             'msg': '获取商品所有信息成功',
                             'count': self.paginator.count,
                             'next': self.paginator.get_next_link(),
                             'previous': self.paginator.get_previous_link(),
                             'data': serializer.data}
            # print(11111)
            return Response(response_data, status=status.HTTP_200_OK)
        # 获取查询集
        queryset = self.get_queryset()
        print(queryset)

        # 获取序列化器实例
        serializer = self.get_serializer(queryset, many=True)
        print(serializer)

        # 获取序列化器的数据
        serialized_data = serializer.data
        print(serialized_data)

        # 添加自定义信息
        response_data = {'code': 100, 'msg': '获取商品所有信息成功', 'data': serialized_data}
        return Response(response_data, status=status.HTTP_200_OK)

    def create(self, request, *args, **kwargs):
        '''
        初始化：调用__init__方法，该方法初始化序列化器。这可能涉及设置一些默认值或初始化实例变量。

        to_internal_value：调用to_internal_value方法，将输入数据（request_data）转换为内部表示。这个步骤包括将JSON数据转换为Python对象。

        validate：调用validate方法，执行整个对象的验证。这是序列化器执行的验证步骤，其中可以包括与整个对象相关的自定义验证逻辑。

        create：如果验证成功，将调用create方法。在这里，您可以执行保存新对象的操作。这个方法通常涉及将数据保存到数据库，然后返回创建的对象。

        to_representation：最后，调用to_representation方法，将创建的对象转换为Python数据结构。这包括在CommoditySerializer中指定的所有字段。

        转换为JSON格式：将to_representation中的数据结构转换为JSON格式。这个过程由Django Rest Framework的默认实现处理。

        序列化：然后，JSON数据由serializer.data返回，这是一个触发内部序列化过程的属性。

        因此，create方法主要涉及将输入数据转换为内部表示，执行验证和保存新对象的操作，并最终将创建的对象序列化为JSON格式。
        '''
        # 获取请求数据
        request_data = request.data

        # 获取序列化器实例
        serializer = self.get_serializer(data=request_data)

        # 验证并保存数据
        serializer.is_valid(raise_exception=True)
        serializer.save()

        # 获取序列化器的数据
        serialized_data = serializer.data

        # 添加自定义信息
        response_data = {'code': 100, 'msg': '添加商品成功', 'data': serialized_data}
        return Response(response_data, status=status.HTTP_201_CREATED)


class CommodityRetrieveUpdateDestroyView(generics.RetrieveUpdateDestroyAPIView):
    queryset = Commodity.objects.all()
    serializer_class = CommoditySerializer
    authentication_classes = []  # 局部禁用
    permission_classes = []
    throttle_classes = []

    def retrieve(self, request, *args, **kwargs):
        '''
        retrieve 方法：
        调用 CommoditySerializer.to_representation 方法，将商品对象转换为 JSON 表示。
        在 to_representation 方法中，你可以添加额外的字段或进行自定义转换。
        返回 JSON 表示，包括自定义信息和商品的字段。
        '''
        # 使用动态参数获取商品对象
        commodity = self.get_object()
        serializer = self.get_serializer(commodity)

        # 在检索视图中添加自定义信息
        response_data = {'code': 100,
                         'msg': '获取指定商品成功',
                         'data': serializer.data}
        return Response(response_data, status=status.HTTP_200_OK)

    def update(self, request, *args, **kwargs):
        '''
        update 方法：
        调用 CommoditySerializer.to_internal_value 方法，将输入数据转换为内部表示。
        调用 CommoditySerializer.validate 方法，对整个对象进行验证。
        调用 CommoditySerializer.update 方法，执行更新操作。在这个方法中，你可以自定义更新逻辑。
        返回更新后的商品对象，通常会再调用 CommoditySerializer.to_representation 方法，将更新后的对象转换为 JSON 表示。
        返回 JSON 表示，包括自定义信息和商品的字段。
        '''
        # 使用动态参数获取商品对象
        commodity = self.get_object()
        print(commodity)

        # 获取序列化器实例，并传入要更新的商品对象和请求的数据
        serializer = self.get_serializer(commodity, data=request.data, partial=True)
        serializer.is_valid(raise_exception=True)

        serializer.save()

        # 调用 serializer.save() 来保存更改
        # result = super().update(request, *args, **kwargs)
        # print(result)
        # 在更新视图中添加自定义信息
        response_data = {'code': 100,
                         'msg': '更新指定商品成功',
                         'data': {'commodity_name': commodity.name}}
        # 'data': {'commodity_name': result}}
        return Response(response_data, status=status.HTTP_200_OK)

    def destroy(self, request, *args, **kwargs):
        '''
        destroy 方法：
        调用 CommoditySerializer.to_representation 方法，将商品对象转换为 JSON 表示。
        返回 JSON 表示，包括自定义信息和商品的字段。
        '''
        # 使用动态参数获取商品对象
        commodity = self.get_object()
        commodity.delete()

        # 在删除视图中添加自定义信息
        response_data = {'code': 100,
                         'msg': '删除指定商品成功',
                         'data': {'commodity_name': commodity.name}}
        return Response(response_data, status=status.HTTP_200_OK)


class ProductSearchAPIView(generics.ListAPIView):
    serializer_class = ProductSeachSerializer
    authentication_classes = []  # 局部禁用
    permission_classes = []
    throttle_classes = []

    def get_queryset(self):
        team_id = self.request.headers.get('team')  # 获取请求头中的门店ID
        queryset = Product.objects.all()  # 获取所有产品

        if team_id:
            print(team_id)
            queryset = queryset.filter(team_id=team_id)  # 根据门店ID进行过滤

        query = self.request.query_params.get('name', '')  # 获取查询参数
        if query:
            queryset = queryset.filter(name__icontains=query)  # 模糊查询产品名称

        return queryset


class DishSearchAPIView(generics.ListAPIView):
    serializer_class = DishSeachSerializer
    authentication_classes = []  # 局部禁用
    permission_classes = []
    throttle_classes = []

    def get_queryset(self):
        team_id = self.request.headers.get('team')  # 获取请求头中的门店ID
        queryset = Dish.objects.all()  # 获取所有产品

        if team_id:
            print(team_id)
            queryset = queryset.filter(team_id=team_id)  # 根据门店ID进行过滤

        query = self.request.query_params.get('name', '')  # 获取查询参数
        if query:
            queryset = queryset.filter(name__icontains=query)  # 模糊查询产品名称

        return queryset


class SalesRecordView(CreateModelMixin,
                      ListModelMixin,
                      RetrieveModelMixin,
                      UpdateModelMixin,
                      DestroyModelMixin,
                      GenericViewSet):
    queryset = SalesRecord.objects.all()
    serializer_class = SalesRecordSerializer
    authentication_classes = []  # 局部禁用
    permission_classes = []
    throttle_classes = []
    pagination_class = MyPagination  # 选择分页类

    def get_queryset(self):
        # 获取前端传入的日期字符串
        created_at = self.request.query_params.get('created_at')
        # store_id = self.request.headers.get('team')  # 获取请求头中的门店ID

        queryset = SalesRecord.objects.all()

        # if store_id:
        #     # 根据门店ID过滤查询结果
        #     queryset = queryset.filter(team=int(store_id))

        if created_at:
            # 如果日期字符串不为空，则解析日期字符串成为datetime对象，并过滤记录
            created_at = timezone.datetime.strptime(created_at, '%Y-%m-%d')
            queryset = queryset.filter(created_at__date=created_at)

        return queryset.order_by('-created_at')  # 按照 created_at 字段的倒序排序

    def create(self, request, *args, **kwargs):
        # serializer = self.get_serializer(data=request.data)
        serializer = self.get_serializer(data=request.data, many=isinstance(request.data, list))
        serializer.is_valid(raise_exception=True)
        self.perform_create(serializer)
        return APIResponse(data=serializer.data, status=status.HTTP_201_CREATED)

    def list(self, request, *args, **kwargs):
        res = super().list(request, *args, **kwargs)
        return APIResponse(data=res.data)

    def retrieve(self, request, *args, **kwargs):
        res = super().retrieve(request, *args, **kwargs)
        return APIResponse(data=res.data)

    def update(self, request, *args, **kwargs):
        res = super().update(request, *args, **kwargs)
        return APIResponse(data=res.data)

    def destroy(self, request, *args, **kwargs):
        instance = self.get_object()

        # 获取销售记录对应的菜品
        dish = instance.dish
        # 获取销售记录对应的销售数量
        sales_quantity = int(instance.sales_quantity)

        # 获取销售记录对应的菜品货品对应关系
        dish_products = dish.dish_products.all()
        with transaction.atomic():
            # 逐个处理销售记录对应的货品库存
            for dish_product in dish_products:
                product = dish_product.product
                # 尝试获取库存表中该货品的最新记录
                latest_inventory = Inventory.objects.filter(product=product).order_by('-created_at').first()

                if latest_inventory:
                    # print(int(sales_quantity) ,int(dish_product.quantity),type(sales_quantity) ,type(dish_product.quantity))
                    # # 更新当前库存数量
                    # print(type(latest_inventory.current_stock))
                    # latest_inventory.current_stock += int(sales_quantity) * int(dish_product.quantity)
                    # latest_inventory.save()
                    # 将库存数量转换为整数类型，并确保有效
                    current_stock = int(latest_inventory.current_stock) if latest_inventory.current_stock else 0

                    # 更新当前库存数量
                    latest_inventory.current_stock = current_stock + (int(sales_quantity) * int(dish_product.quantity))
                    latest_inventory.save()

        # 删除销售记录
        self.perform_destroy(instance)
        return APIResponse(data='删除成功')


from rest_framework.views import APIView
from rest_framework.parsers import MultiPartParser
from rest_framework.response import Response
from rest_framework import status
from django.db import transaction
import pandas as pd


# 假设 read_excel_file 是一个可以读取Excel文件并返回字典列表的函数
def read_excel_file(file_obj):
    df = pd.read_excel(file_obj)

    field_mapping = {
        '品名': 'name',
        '分类': 'category',
        '单位（克，斤、公斤、毫升、升）': 'unit',
        '单价': 'product_price',
        '成本价': 'product_cost_price',
        '数量': 'quantity',
        '备注': 'description',
        '采购日期（2024-06-06）': 'stock_in_time'
    }

    data_list = df.to_dict(orient='records')

    converted_data_list = []
    for row in data_list:
        product_data = {}
        invent_in_db = {}
        for zh_field, value in row.items():
            if zh_field in field_mapping:
                en_field = field_mapping[zh_field]
                if en_field in ['product_price', 'quantity', 'weight', 'stock_in_time', 'stock_out_quantity']:
                    invent_in_db[en_field] = value
                else:
                    product_data[en_field] = value
        product_data['invent_in_db'] = invent_in_db
        converted_data_list.append(product_data)

    return converted_data_list


class BulkProductUploadView(APIView):
    parser_classes = [MultiPartParser]
    throttle_classes = []

    @transaction.atomic
    def post(self, request, *args, **kwargs):
        file_obj = request.data['file']
        product_data = read_excel_file(file_obj)
        team_id = request.headers.get('team')  # 从请求头中获取门店ID

        # 打印读取的数据
        for row in product_data:
            print(row)
            # 确保stock_in_time是字符串
            if isinstance(row['invent_in_db']['stock_in_time'], pd.Timestamp):
                row['stock_in_time'] = row['stock_in_time'].strftime('%Y-%m-%d')

            # 获取 category 和 unit 的名称
            category_name = row['category']
            unit_name = row['unit']

            # 查询数据库获取对应的 ID
            # 查询数据库获取对应的 ID，考虑门店ID
            try:
                category_id = ProductCategory.objects.get(name=category_name, team_id=team_id).category_id
            except ProductCategory.DoesNotExist:
                return Response({'error': f'Category "{category_name}" for team "{team_id}" does not exist.'},
                                status=status.HTTP_400_BAD_REQUEST)
            try:
                unit_id = Unit.objects.get(name=unit_name).unit_id
            except Unit.DoesNotExist:
                return Response({'error': f'Unit "{unit_name}" does not exist.'},
                                status=status.HTTP_400_BAD_REQUEST)

            product_data = {
                'name': row['name'],
                'category': category_id,
                # 'category': row['category'],
                'unit': unit_id,
                # 'unit': row['unit'],
                # 'team': row['team'],
                'description': row['description'],
                'invent_in_db': {
                    'product_price': row.get('product_price', 1),
                    'product_cost_price': row.get('product_cost_price', 0),
                    'quantity': row.get('quantity', 1),
                    'weight': row.get('weight', 0),
                    # 'stock_in_time': row.get('stock_in_time', 0),
                    'stock_out_quantity': row.get('stock_out_quantity', 0)
                }
            }

            serializer = CreateSerializer(data=product_data)
            if serializer.is_valid():
                serializer.save()
            else:
                return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

        return Response({"message": "Products uploaded successfully"}, status=status.HTTP_201_CREATED)
